'use strict';
var vk; // 全局vk实例
// 涉及的表名
const dbName = {
	//test: "vk-test", // 测试表
};

var db = uniCloud.database(); // 全局数据库引用
var _ = db.command; // 数据库操作符
var $ = _.aggregate; // 聚合查询操作符
const keyName = `sys-pub.reward.run`;
/**
 * 权限注意：访问以下链接查看
 * 文档地址：https://vkdoc.fsq.pub/client/uniCloud/cloudfunctions/cloudObject.html#内置权限
 */
var cloudObject = {
	isCloudObject: true, // 标记为云对象模式
	/**
	 * 请求前处理，主要用于调用方法之前进行预处理，一般用于拦截器、统一的身份验证、参数校验、定义全局对象等。
	 * 文档地址：https://vkdoc.fsq.pub/client/uniCloud/cloudfunctions/cloudObject.html#before-预处理
	 */
	_before: async function() {
		vk = this.vk; // 将vk定义为全局对象
		// let { customUtil, uniID, config, pubFun } = this.getUtil(); // 获取工具包
	},
	/**
	 * 请求后处理，主要用于处理本次调用方法的返回结果或者抛出的错误
	 * 文档地址：https://vkdoc.fsq.pub/client/uniCloud/cloudfunctions/cloudObject.html#after-后处理
	 */
	_after: async function(options) {
		let { err, res } = options;
		if (err) {
			return; // 如果方法抛出错误，直接return;不处理
		}
		return res;
	},
	/**
	 * 运行一次奖励任务
	 * @url rewardMode/pub.reward.run 前端调用的url参数地址
	 */
	run: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			key
		} = data;
		if (key !== "f766913ec9ac3d438c783d6a6a1c005b") return { code: -1, msg: "" };
		let time = Date.now();
		// 按时间获取最早一个未执行的任务
		let taskInfo = await vk.daoCenter.orderTaskDao.findOne();
		if (vk.pubfn.isNull(taskInfo)) return { code: 0, msg: '无任务执行' };
		let {
			order_no, // 商户订单号
			type, // 任务类型
		} = taskInfo;
		let workCache = await vk.globalDataCache.get(keyName);
		if (vk.pubfn.isNotNull(workCache) && workCache.runing) {
			return { code: -1, msg: '正在执行中...' };
		}
		// 标记任务机,现在工作中
		await vk.globalDataCache.set(keyName, { runing: true, time }, 15);

		// 获取订单信息
		let orderInfo = await vk.daoCenter.orderDao.findByOrderNo(order_no);
		if (vk.pubfn.isNull(orderInfo)) {
			// 标记任务为执行失败
			let msg = `单号【${order_no}】：订单不存在`;
			await vk.daoCenter.orderTaskDao.updateStatusError({
				taskInfo,
				msg
			});
			return await this._returnRes({ code: -1, msg }, taskInfo, orderInfo);
		}
		let {
			user_id,
		} = orderInfo;

		if (type === 1002) {
			// 需要判断订单是否已结算，如果未结算，则本次退款无需结算，若已结算，则本次退款需要扣除相应的奖励
			// 获取成功支付的任务记录
			let taskInfo2 = await vk.daoCenter.orderTaskDao.findByWhereJson({
				order_no,
				type: 1001,
			});
			if (vk.pubfn.isNull(taskInfo2) || taskInfo2.status !== 2) {
				// 如果付款任务未找到 或 订单未结算，则本次退款也无需结算
				// 标记任务无需执行
				let msg = `单号【${order_no}】：订单未结算，本次退款无需结算`;
				await vk.daoCenter.orderTaskDao.updateStatusNoExecute({
					taskInfo,
					msg
				});
				console.log(msg);
				return await this._returnRes({ code: 0, msg }, taskInfo, orderInfo);
			}
		}

		let fx_mode = vk.pubfn.getData(orderInfo, "fx.mode", "none");

		let userInfo = await vk.daoCenter.userDao.findById(user_id);
		if (vk.pubfn.isNull(userInfo)) {
			// 标记任务为执行失败
			let msg = `用户[${user_id}]不存在，订单号：${order_no}`;
			await vk.daoCenter.orderTaskDao.updateStatusError({
				taskInfo,
				msg
			});
			return await this._returnRes({ code: -1, msg }, taskInfo, orderInfo);
		}
		let typeObj = {
			1001: "订单付款",
			1002: "订单退款"
		};
		let taskService;
		try {
			console.log(`正在加载分销模式【${fx_mode}】类型【${type}：${typeObj[type]}】单号【${order_no}】`)
			taskService = vk.require(`service/rewardMode/mode/${fx_mode}/type/${type}`);
		} catch (err) {
			console.error("编译错误", err);
		}
		if (!taskService) {
			// 标记任务为执行失败
			let msg = `分销模式【${fx_mode}】的类型【${type}：${typeObj[type]}】编译错误`;
			await vk.daoCenter.orderTaskDao.updateStatusError({
				taskInfo,
				msg
			});
			return await this._returnRes({ code: -1, msg }, taskInfo, orderInfo);
			// 此处可以发送通知给管理员
		}
		let mchInfo = await vk.daoCenter.mchDao.find();
		try {
			console.log(`正在执行分销模式【${fx_mode}】类型【${type}：${typeObj[type]}】单号【${order_no}】`)
			res = await taskService.run({
				taskInfo,
				orderInfo,
				userInfo,
				mchInfo
			});
		} catch (err) {
			console.log("运行错误", err);
			res = { code: -1, msg: "运行错误" + err.message };
		}
		// 业务逻辑结束-----------------------------------------------------------
		return await this._returnRes(res, taskInfo, orderInfo);
	},
	/**
	 * 模板函数
	 * @url rewardMode/pub.reward.test 前端调用的url参数地址
	 */
	test: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------


		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 统一返回
	 * @url rewardMode/pub.reward._returnRes 前端调用的url参数地址
	 */
	_returnRes: async function(res, taskInfo, orderInfo) {
		// 业务逻辑开始-----------------------------------------------------------
		await vk.globalDataCache.del(keyName);
		if (res.code !== 0) {
			// 发邮件通知管理员
			let title = `异常内容：${res.msg}，异常任务id：${taskInfo._id}`;
			// await vk.baseDao.add({
			// 	dbName: "vk-async-task",
			// 	dataJson: {
			// 		jisu_appid: taskInfo.jisu_appid,
			// 		status: 0,
			// 		type: "email",
			// 		title: title,
			// 		plan_exec_time: new Date().getTime(),
			// 		data: {
			// 			email: "wxxiao110@163.com",
			// 			subject: "返佣任务异常通知",
			// 			app_info: orderInfo.app_info,
			// 			no:taskInfo._id,
			// 			msg:res.msg,
			// 			type: "error-fanli",// 返佣异常
			// 		}
			// 	}
			// });
		}
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	}
};

module.exports = cloudObject;
